/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.jfonia.view.labels;

import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.JPanel;
import org.jfonia.connect5.basics.BasicValueNode;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.constants.ViewConstants;

/**
 *
 * @author Rik Bauwens
 */
public class LabelPanel extends JPanel implements ILabelsObserver, ComponentListener
{
        private static LabelPanel instance;

        private Map<Label, LabelView> labelViews;
        private Labels labels;
        private MutableValueNode<Double> widthNode;

        private LabelPanel()
        {
                super();
                setVisible(false);
                setLayout(null);
                setPreferredSize(new Dimension(getWidth(), ViewConstants.LABELS_BAR_HEIGHT));
                addComponentListener(this);
                //Linked list for performance reasons
                labelViews = new LinkedHashMap<Label, LabelView>();
                widthNode = new BasicValueNode<Double>(0.0);
        }

        public static synchronized LabelPanel getInstance()
        {
                if(instance == null)
                        instance = new LabelPanel();
                return instance;
        }

        public void setLabels(Labels labels)
        {
                if(this.labels != null)
                        this.labels.removeObserver(this);
                clearLabels();
                this.labels = labels;
                setVisible(false);
                if(labels == null)
                        return;
                for(Label label : labels)
                        addLabel(label);
                labels.addObserver(this);
                setVisible(true);
        }

        private void addLabel(Label label)
        {
                if(labelViews.containsKey(label))
                        return;
                LabelView labelView = new LabelView(label);
                labelViews.put(label, labelView);
                labelView.setWidthNode(widthNode);
                add(labelView);
                repaint();
        }

        private void removeLabel(Label label)
        {
                if(!labelViews.containsKey(label))
                        return;
                LabelView labelView = labelViews.get(label);
                labelViews.remove(label);
                remove(labelView);
                repaint();
        }

        private void clearLabels()
        {
                Iterator<Label> it = labelViews.keySet().iterator();
                while(it.hasNext())
                {
                        remove(labelViews.get(it.next()));
                        it.remove();
                }
                repaint();
        }

        public void labelAdded(Label label)
        {
                addLabel(label);
        }

        public void labelRemoved(Label label)
        {
                removeLabel(label);
        }

        public void componentResized(ComponentEvent e)
        {
                widthNode.setValue(new Double(getWidth()));
        }

        public void componentMoved(ComponentEvent e) {}

        public void componentShown(ComponentEvent e) {}

        public void componentHidden(ComponentEvent e) {}
}
